package plenprojects.chatroomcontrollers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import plenprojects.chatservice.ChatService;
import plenprojects.dao.ChatServiceDao;
import plenprojects.exceptions.AuthenticationException;
import plenprojects.exceptions.RegistrationException;
import plenprojects.model.ServerError;
import plenprojects.model.ServerMessage;
import plenprojects.model.UserDetails;
import plenprojects.security.LoginAuthenticator;
import plenprojects.security.SecurityToken;
import plenprojects.security.UserRegistrationValidator;

@Controller
@RequestMapping("/sec")
public class SecurityController {
	
	@Autowired
	private ChatServiceDao dao;
	
	@Autowired
	private UserRegistrationValidator validator;
	
	@Autowired
	private LoginAuthenticator auth;
	
	@Autowired
	private ChatService service;
	
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody ServerMessage login(@RequestBody ServerMessage request) {
		
		ServerMessage response = new ServerMessage();
		
		String username = (String)request.getParameter("username");
		String password = (String)request.getParameter("password");
		
		try {
			
			auth.authenticate(username, password);
			
		}
		catch(AuthenticationException e) {
			
			return new ServerError(e.getMessage());
		}
		
		if(service.hasToken(username)) {
			
			return new ServerError("User is already logged in.");
		}
		
		SecurityToken token = service.generatePublicAccessToken(username);
		
		response.setParameter("success", true);
		response.setParameter("token", token.toString());
		
		return response;
	}
	
	@RequestMapping(value = "/logout", method = RequestMethod.POST)
	public @ResponseBody ServerMessage logout(@RequestBody ServerMessage request) {
		
		ServerMessage response = new ServerMessage();
		
		String token = (String)request.getParameter("token");
		
		if(token == null) {
			
			return new ServerError("Token value not set.");
		}
		
		if(!service.isValid(token)) {
			
			return new ServerError("Invalid token.");
		}
		
		service.invalidateToken(token);
		
		response.setParameter("success", true);
		
		return response;
	}
	
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public @ResponseBody ServerMessage register(@RequestBody ServerMessage request) {
		
		UserDetails usr = null;
		
		try {
			
			usr = validator.register(request);
			
		}
		catch(RegistrationException e) {
			
			return new ServerError(e.getMessage());
		}
		
		dao.addUser(usr);
		
		ServerMessage response = new ServerMessage();
		
		response.setParameter("success", true);
		return response;
	}
	
	@RequestMapping(value = "/{token}/isvalid", method = RequestMethod.GET)
	public @ResponseBody ServerMessage isValid(@PathVariable String token) {
		
		ServerMessage response = new ServerMessage();
		
		response.setParameter("isvalid", service.isValid(token));
		
		return response;
	}
	
}
